var list = new ArrayList();
var yyyy_MM_dd_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
var yyyyMMdd_PARSER = new SimpleDateFormat("yyyyMMdd");
var yyyy_MM_dd_HH_mm_ss_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
var indexHtml = "";
var appJS = "";
var the_bill_day ="18";
var needReLogin = true;
var RASKEY = "";
var v4_ceb_credit_java_funcs = {
    openHomePage : function(){
        for(var i=0;i<=10;i++){
            Thread.sleep(1000);
            indexHtml =RequestUtil.get("https://xyk.cebbank.com/mall/login?target=/mycard/home/home.htm");
            logger.info("任务：{},开始获取登录的必要参数，获取app.js",context.get(LUA_TASK_KEY));
            Thread.sleep(1000);
            var appjs_url = "https://xyk.cebbank.com/assets/scripts/app-" + RegexUtils.GetText(indexHtml, "/assets/scripts/app-([^.js]*)") + ".js";
            appJS = RequestUtil.get(appjs_url);
            storeDataToFile(context, appJS, "app.js")
            if(!appJS.contains("/images/home/error.jpg")){
                logger.info("成功获取到appjs")
                break;
            }
        }
    },
    checkProxyAvailable : function() {
        logger.info("任务：{}，光大银行信用卡入口检测代理是否可用",context.get(LUA_TASK_KEY));
        //判断是否代理异常的function
        var isCorrectFunc = function(indexHtml){
            var doc = Jsoup.parse(indexHtml);
            return (doc!=null && doc.select("#login")!=null);
        }
        //获取异常信息的方法function
        var getErrorMsgFunc = function(indexHtml) {
            return "代理ip异常";
        }
        //返回信息
        return assertTrueOrThrowException(indexHtml, isCorrectFunc, getErrorMsgFunc)
    },
    checkControlAvailable:function(){
        logger.info("任务：{}，不需要安装控件",context.get(LUA_TASK_KEY));
        return true;
    },
    /**
     * 检查网站是否可用
     * @returns {*}
     */
    checkTargetWebsiteAvailable: function(){
        logger.info("任务taskKey = {}, 进入检查光大银行网站是否可用方法", context.get(LUA_TASK_KEY));
        return true;
    },
    needResetEnvironment:function(){
        return equals(context.get("currentErrorCode"), BALO_99602_50)
    },
    login:function(){
        if(needReLogin){
            logger.info("任务：{}，进入到光大信用卡登录过程",context.get(LUA_TASK_KEY));
            logger.info("--------------------------------------LOGIN START---------------------------------------------")
            RASKEY = RegexUtils.GetText(appJS, "payPrimaryKay:\"([^\"]*?)\"");
            if(StringUtils.isBlank(RASKEY)){
                //可能会多空格
                RASKEY = RegexUtils.GetText(appJS, "payPrimaryKay: \"([^\"]*?)\"");
            }
            logger.info("任务：{},参数获取完成，获取到的动态加密参数为:{}",context.get(LUA_TASK_KEY),RASKEY);
            storeDataToFile(context, indexHtml, "loginHtml.html")

            //------------------------------------判断用户的登录方式是否正确，获取登录用户名密码-------------------------------------
            logger.info("任务：{},从上下文中获取登录参数，判断登录方式是否正确",context.get(LUA_TASK_KEY));
            var loginTypeMsg = "true";
            if (equals(LoginType.CARDNO.toString(),context.get(LUA_TASK_LOGIN_TYPE))) {
                logger.info("任务：{}，登录方式为卡号登录",context.get(LUA_TASK_KEY))
                var cardNo = getLoginParams(context)[0];
                context.put("name", cardNo);
            } else if (equals(LoginType.IDCARD.toString(),context.get(LUA_TASK_LOGIN_TYPE))) {
                logger.info("任务：{},登录方式为身份证号登录",context.get(LUA_TASK_KEY))
                var certNo = getLoginParams(context)[0];
                context.put("name", certNo);
                //将获取的身份证号中的x或者X或者a或者A替换为""
                var checkCard = certNo.replaceAll("x|X|a|A", "");
                logger.info("任务：{}，判断身份证是否符合正则表达式,certNo：{}，结果：{}",context.get(LUA_TASK_KEY),certNo,isStringToNumber(checkCard));
                if (certNo.length() > 18 || !isStringToNumber(checkCard)) {
                    loginTypeMsg = "尚未注册或无此用户";
                }
            } else {
                logger.info("任务：{}，登录方式错误",context.get(LUA_TASK_KEY));
                loginTypeMsg = "该银行不支持卡号登录方式";
            }
            //判断登录方式流程正确性
            var isLoginTypeCorrectFunc = function(loginTypeMsg){
                if(loginTypeMsg.equals("true")){
                    return true
                }else{
                    return false
                }
            }
            //获取登录方式的错误信息
            var getLoginTypeErrMsg = function (loginTypeMsg) {
                return loginTypeMsg;
            }
            assertTrueOrThrowException(loginTypeMsg, isLoginTypeCorrectFunc, getLoginTypeErrMsg);
            logger.info("任务：{},登录参数获取成功，登录方式正确",context.get(LUA_TASK_KEY));

            //---------------------------------输入图片验证码--发送短信-----------------------------------------------
            var dynamic = getImgAndSendSms();
            storeDataToFile(context, dynamic, "dynamic1.txt")
            if(strIsJSON(dynamic)){
                //说明发送频繁
                var object = JSON.parseObject(dynamic);
                var dataStr = object.getString("data");
                var sleep_time = 0;
                if(object.getString("status").equals("200") && /^[\d+]+$/.test(object.getJSONObject("data").getString("result")) && parseInt(object.getJSONObject("data").getString("result")) < 60){
                    sleep_time = (parseInt(object.getJSONObject("data").getString("result"))) * 1000;
                }else if(dataStr.contains(",")){
                    var data = JSON.parseObject(dataStr).getString("result");
                    var timeArr = data.split(",");
                    if(parseInt(timeArr[0]) < 60){
                        sleep_time = parseInt(timeArr[0]) * 1000
                    }
                }
                if(sleep_time > 0){
                    logger.info("任务：【{}】，发送短信需要休眠【{}】毫秒",context.get(LUA_TASK_KEY),sleep_time)
                    logger.info("开始休眠【{}】===============================",context.get(LUA_TASK_KEY))
                    Thread.sleep(sleep_time)
                    logger.info("结束休眠【{}】===============================",context.get(LUA_TASK_KEY))
                    //休眠够了之后再重新调用一次
                    dynamic = getImgAndSendSms();
                    storeDataToFile(context, dynamic, "dynamic2.txt")
                }
            }
            //判断短信验证码发送的流程正确性 获取短信验证码时会验证身份证号或者其余的信息格式是否正确，根据返回的结果判断是否输入的信息是否正确
            var isSendSmsCorrectFunc = function (dynamic) {
                //如果返回的status码是200表示登录成功
                if(strIsJSON(dynamic)){
                    var object = JSON.parseObject(dynamic);
                    var status = object.getString("status");
                    if (status!=null && status.equals("200")) {
                        var res = object.getJSONObject("data").getString("result")
                        if(res.contains(",")){
                            var time = res.split(",");
                            if(parseInt(time[0]) < 60){
                                return false;
                            }
                        }else{
                            if(parseInt(res) < 60){
                                return false;
                            }
                        }
                        return true;
                    }else{
                        return false;
                    }
                }else{
                    return false;
                }
            }
            //获取图片验证码和短信验证码的错误信息
            var getSendSmsErrMsg = function (dynamic) {
                if(strIsJSON(dynamic)){
                    var object = JSON.parseObject(dynamic);
                    var res = object.getJSONObject("data").getString("result")
                    if(res.contains(",")){
                        var time = res.split(",");
                        if(object.getString("status").equals("200") && /^[\d+]+$/.test(time[0]) && parseInt(time[0]) < 60){
                            return "短信验证码发送频繁，请稍后再试";
                        }
                    }else{
                        if(object.getString("status").equals("200") && /^[\d+]+$/.test(object.getJSONObject("data").getString("result")) && parseInt(object.getJSONObject("data").getString("result")) < 60){
                            return "短信验证码发送频繁，请稍后再试";
                        }
                    }
                }
                return StringUtils.isNotBlank(dynamic) ? dynamic.trim().replace(/[\r\n]/g, '') : "";;
            }
            assertTrueOrThrowException(dynamic, isSendSmsCorrectFunc, getSendSmsErrMsg);
            logger.info("任务：{},图片验证码校验成功，短信验证码发送成功",context.get(LUA_TASK_KEY));
        }

        //-----------------------------------------开始校验短信验证码是否正确---------------------------------------
        logger.info("任务：{}，开始获取并校验用户输入的短信验证码是否正确",context.get(LUA_TASK_KEY));
        var smsCheckMsg = "";
        var waitstartTime = System.currentTimeMillis();
        var  verifyMessage = waitSmsCodeBySeconds(context,120);
        var waitEndTime = System.currentTimeMillis();
        logger.info("任务【{}】，等待用户短信时长【{}】",context.get(LUA_TASK_KEY),waitEndTime-waitstartTime)

        var startTime = System.currentTimeMillis();
        logger.info("任务【{}】，收到用户短信，当前时间戳【{}】",context.get(LUA_TASK_KEY),startTime)
        logger.info("任务：{},获取到的短信验证码为：{}",context.get(LUA_TASK_KEY),verifyMessage)
        //校验短信验证码的格式是否正确的流程，错误的话不继续向下进行
        var isSmsLengthCorrectFunc = function (verifyMessage) {
            return StringUtils.isNotBlank(verifyMessage) && verifyMessage.length === 6;
        }
        var getSmsLengthErrMsg = function (verifyMessage) {
            needReLogin = false;
            return "短信验证码错误";
        }
        assertTrueOrThrowException(verifyMessage, isSmsLengthCorrectFunc, getSmsLengthErrMsg);
        logger.info("任务：{},用户输入的短信验证码格式符合要求",context.get(LUA_TASK_KEY));

        logger.info("任务：{}，开始加载js对密码进行rsa加密",context.get(LUA_TASK_KEY));
        var scriptEngineManager = new ScriptEngineManager();
        var eg = scriptEngineManager.getEngineByName("JavaScript");
        eg.eval("load('js/ceb/ceb.js')");
        var readyState =  eg.eval("RSATEST('" + verifyMessage + "','" + RASKEY + "')");
        logger.info("任务：{}，密码加密之后：{}",context.get(LUA_TASK_KEY), readyState);
        var code =  context.get("code");
        var name =  context.get("name");
        Thread.sleep(1000);
        var map = new HashMap();
        map.put("code", code);
        map.put("password", readyState);
        map.put("target", "/mycard/home/home.htm");
        map.put("userName", name);
        //登录
        var loginHtml = RequestUtil.post("https://xyk.cebbank.com/mall/api/user/login?t=" + Math.floor(Math.random() * 10000000), map);
        storeDataToFile(context, loginHtml, "smsCheck.html")
        logger.info("任务：{}，短信验证码校验完成，官网返回：{}",context.get(LUA_TASK_KEY),loginHtml);
        //校验短信验证码是否正确的流程
        var smsCheckResultCorrectFunc = function (loginHtml) {
            if(strIsJSON(loginHtml)){
                var object = JSON.parseObject(loginHtml);
                var status = object.getString("status");
                //判断是否为200，如果为200表示登录成功，否则登录失败
                if (StringUtils.isNotBlank(status) && status.equals("200")) {
                    return true;
                } else {
                    return false;
                }
            }else{
                return false;
            }
        }
        //获取短信验证码校验的错误提示信息方法
        var getSmsCodeCheckErrMsg = function (loginHtml) {
            if (StringUtils.isEmpty(loginHtml)) {
                return "短信验证码超时"
            }else if(loginHtml.contains("BBBBBBB")){
                var error_count = loginHtml.trim().replace(/[\r\n]/g, '').substring(7,8);
                needReLogin = false;
                return "校验动态密码失败，您已检验失败" + error_count + "次";
            }else if(loginHtml.contains("CCCCCCC")){
                needReLogin = true;
                return "校验动态密码失败，已超过5次，请重新获取";
            }else if(loginHtml.contains("DDDDDDD")){
                needReLogin = true;
                return "校验动态密码超时，15分钟之内有效，请重新获取";
            }else if(loginHtml.contains("EEEEEEE")){
                needReLogin = true;
                return "校验动态密码超时，请重新获取";
            }else if(loginHtml.contains("GGGGGGG")){
                needReLogin = true;
                return "动态密码已失效，请重新获取";
            }else if(loginHtml.contains("FFFFFFF")){
                needReLogin = true;
                return "图片验证码错误";
            } else{
                return StringUtils.isNotBlank(loginHtml) ? loginHtml.trim().replace(/[\r\n]/g, '') : "";
            }
        }
        var endTime = System.currentTimeMillis();
        logger.info("任务【{}】，用户登录结束，从收到短信到登录结束用时【{}】",context.get(LUA_TASK_KEY),(endTime - startTime))
        logger.info("------------------------------------------------LOGIN END-------------------------------------------------")
        assertTrueOrThrowException(loginHtml, smsCheckResultCorrectFunc, getSmsCodeCheckErrMsg);
    },
    crawl:crawl,
    exitLogin: function () {}
}

/**
 * 获取图片校验码和发短信单独抽取出来，以便重试
 */
function getImgAndSendSms(){
    logger.info("任务：{},开始获取图片验证码base64并由打码平台自动打码",context.get(LUA_TASK_KEY));
    var captcha = RequestUtil.getAsBytes("https://xyk.cebbank.com/mall/api/captcha?" + Math.floor(Math.random() * 10000000));
    context.put(TASK_IMG_BYTES, captcha);
    context.put(TASK_IMG_REGEX,"[0-9a-zA-Z]{4}");
    var code = waitImgCodeBySecondsByJs(context,60,true,3)
    logger.info("任务：{},图片验证码自动打码完成，code：{}",context.get(LUA_TASK_KEY),code);

    //---------------------------------判断图片验证码  发送短信验证码--------------------------------------
    logger.info("任务：{},开始校验图片验证码，如果校验成功将会自动发送短信验证码",context.get(LUA_TASK_KEY));
    var parametersMap = new HashMap();
    var name =  context.get("name");
    parametersMap.put("name", name);
    parametersMap.put("code", code.toLowerCase());
    var dynamic = RequestUtil.post("https://xyk.cebbank.com/mall/api/usercommon/dynamic", parametersMap);
    context.put("code", code.toLowerCase());
    logger.info("任务：{}，图片验证码校验/短信验证码发送，返回结果：{}", context.get(LUA_TASK_KEY) ,dynamic);
    return dynamic;
}

/**
 * 抓取数据
 */
function crawl() {
    Thread.sleep(1000);
    logger.info("任务【 {} 】-延迟两秒",  context.get(LUA_TASK_KEY));

    //获取登录后的页面
    var firstHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/home/home.htm");
    //重试10次，防止网络原因导致失败
    for(var i=0;i<10;i++){
        if(firstHtml.contains("Error 404--Not")){
            logger.info("任务【 {} 】-重试链接",context.get(LUA_TASK_KEY));
            Thread.sleep(1000);
            firstHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/home/home.htm");
        }else{
            logger.info("任务【 {} 】-重试成功",context.get(LUA_TASK_KEY));
            break;
        }
    }
    //保存页面
    storeDataToFile(context, firstHtml, "firstHtml.html")
    //解析登录后的页面
    var firstDoc = Jsoup.parse(firstHtml);
    //获取持卡人姓名
    var name_on_card = firstDoc.select("#logined > p > strong").text().replaceAll(",", "");
    logger.info("任务【 {} 】-延迟一秒",  context.get(LUA_TASK_KEY));
    Thread.sleep(1000);
    //获取卡片信息
    var cardsHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/home/acclist.htm?num=" + Math.floor(Math.random() * 10000000));
    //保存页面
    storeDataToFile(context, cardsHtml, "cardsHtml.html")
    //解析页面
    var doc = Jsoup.parse(cardsHtml);
    //获取卡片
    var tab99 = doc.select("[class='tab99']");
    //如果获取到的长度为0，则说明没有卡片信息
    if (tab99.size() == 0) {
        throw new BankException(BALO_20304_30, errorMsgMap.get(BALO_20304_30));
    }
    for (var i = 0; i < tab99.size(); i++) {
        // 声明存储对象
        var creditCardAllData = new CreditCardAllData();
        // 声明存储金额列表
        var deposits = new ArrayList();
        // 声明账单列表
        var bills = new ArrayList();
        creditCardAllData.setBills(bills);
        creditCardAllData.setDeposits(deposits);

        //卡类型
        creditCardAllData.setCardType("信用卡");
        //银行
        creditCardAllData.setBankName("光大银行");
        //卡编号
        creditCardAllData.setCardId(UUID.randomUUID().toString());
        //预借现金额度
        creditCardAllData.setCashBalance(null);
        //持卡人姓名
        creditCardAllData.setNameOnCard(name_on_card.replaceAll(",", ""));
        var billTds = tab99.get(i).select("td");
        var td3 = billTds.get(3);
        //获取a标签
        var a = td3.getElementsByTag("a").get(1);
        //获取其onclick属性
        var onclick = a.attr("onclick");
        //将获取到的地址按照'分割
        var params = onclick.split("'");
        //完整卡号
        var full_card_num = params[1];
        //卡号后四位
        var card_num = full_card_num.substring(
            full_card_num.length() - 4, full_card_num.length());
        context.put("shopping_card_num",card_num);
        creditCardAllData.setFullCardNum(full_card_num);
        creditCardAllData.setCardNum(card_num);
        creditCardAllData.setOpenBank("光大银行");//开户银行
        //creditCardAllData.setOpenTime("");

        // 基本信息
        var baseHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/bill/info.htm");
        //保存页面
        storeDataToFile(context, baseHtml, "baseHtml.html")
        var postdata = new HashMap();
        //获取请求参数
        paraseBaseParams(baseHtml, postdata, full_card_num);
        //查询账户信息
        var userHtml = RequestUtil.post("https://xyk.cebbank.com/mycard/bill/info.htm", postdata);
        //保存页面
        storeDataToFile(context, userHtml, i + "_userHtml.html")
        var map = new HashMap();
        //获取账户信息
        paraseUserHtml(userHtml, creditCardAllData, map);

        //获取账单页面
        var billsHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/bill/havingprintbill-query.htm");
        //保存页面
        storeDataToFile(context, billsHtml, i + "billsHtml.html")
        if (billsHtml.contains("对不起！") && billsHtml.contains("未知错误")) {
            logger.error("任务"+  context.get(LUA_TASK_KEY) + "账单信息-:无账单记录");
        } else {
            //解析账单页面
            var billsDoc = Jsoup.parse(billsHtml);
            var tab_one = billsDoc.select("[class='tab_one']");
            var tab = tab_one.get(0);
            //获取其tr属性
            var trs = tab.select("tr");
            for (var j = trs.size() - 1; j >= 1; j--) {
                var tr = trs.get(j);
                var tds = tr.select("td");
                var td0 = tds.get(0);
                var scriptE = td0.getElementsByTag("script").get(0);
                var scriptList = scriptE.dataNodes();
                var datanode = scriptList.get(0);
                var script = datanode.toString();
                var format = RegexUtils.GetText(script, "formatDate8to10\\('\\d{8}");
                if (StringUtils.isNotEmpty(format)) {
                    //账单月份
                    var bill_moth = RegexUtils.GetText(format, "\\d{8}");
                    logger.info("账单月份：" + bill_moth);
                    try {
                        //获取该月份的账单信息
                        //休眠1秒，频繁请求会有未知错误
                        Thread.sleep(1000)
                        var billHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/bill/billquerydetail.htm?statementDate=" + bill_moth);
                        //保存页面
                        storeDataToFile(context, billHtml, i + "_billHtml_" + j + ".html")
                        if (billHtml.contains("对不起！") && billHtml.contains("未知错误")) {
                            //页面返回未知错误，跳过这个月的账单，继续向下抓取
                            logger.info("taskKey={},光大银行，页面返回未知错误，跳过改月账单，继续进行",context.get(LUA_TASK_KEY))
                            continue;
                        }
                        //解析账单页面
                        paraseBillHtml(billHtml, bills, bill_moth);
                    } catch (e) {
                        logger.error("taskKey={} 账单月份抓取异常：{}", context.get(LUA_TASK_KEY), e);
                        statCaughtException(context, e);
                    }
                }
            }
        }
        // 未出
        paraseunBills(full_card_num, i, bills, map);

        list.add(creditCardAllData);
    }
    context.put("credit_data", list);
}

/**
 * 判断传入的值是否否则该正则表达式
 * @param str
 * @returns {*}
 */
function isStringToNumber( str) {
    var pattern = Pattern.compile("^[0-9]+$");
    var match = pattern.matcher(str);
    return match.matches();
}

/**
 * 解析账户信息
 * @param userHtml
 * @param creditCardAllData
 * @param map
 */
function paraseUserHtml( userHtml,  creditCardAllData,  map) {
    //解析账户信息
    var doc = Jsoup.parse(userHtml);
    var trs = doc.select("#formshow > td > table > tbody > tr");
    logger.info("");
    for each (var tr in trs) {
        var tds = tr.select("td");
        if (tds.size() == 0) {
            continue;
        }
        //取其td标签的值并判断
        var td = tds.get(0).text();
        //根据描述取出对应的值
        if (td.contains("信用额度")) {
            creditCardAllData.setCreditLimit(getBigDecimalByString(tds
                .get(1).text()));
            map.put("credit_limit", tds.get(1).text());
        } else if (td.contains("预借现金额度")) {
            creditCardAllData.setCashLimit(getBigDecimalByString(tds
                .get(1).text()));
            context.put("cash_limit",getBigDecimalByString(tds.get(1).text()))
        } else if (td.contains("实际可用额度")) {
            if (tds.get(1).text().contains("超限")) {
                creditCardAllData.setBalance(getBigDecimalByString(
                    tds.get(1).text().replaceAll("超限|元", "")).negate());
            } else {
                creditCardAllData.setBalance(getBigDecimalByString(tds.get(
                    1).text()));
            }
        } else if (td.contains("账单日")) {

        } else if (td.contains("到期还款日")) {
            map.put("payment_due_date", tds.get(1).text());
        } else if (td.contains("本期账单应还款额")) {
            map.put("new_balance", tds.get(1).text().replaceAll("账单分期", ""));
        } else if (td.contains("本期最小还款额")) {
            map.put("min_payment", tds.get(1).text());
        }

    }
}

/**
 * 解析未出账单
 * @param full_card_num
 * @param i
 * @param bills
 * @param map
 */
function paraseunBills( full_card_num,  i, bills,  map) {
    //请求未出账单地址
    var unbillsHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/bill/unprintbill.htm");
    //保存页面
    storeDataToFile(context, unbillsHtml, "unbillsHtml.html")
    var num = 1;
    //请求改卡号的未出账单信息
    var unbillHtml = RequestUtil.get("https://xyk.cebbank.com/mycard/bill/unprintbill-query.htm?ACCT_NBR="
        + full_card_num + "&ORG=102");
    //保存页面信息
    storeDataToFile(context, unbillHtml, i + "_unbillHtml_0.html")
    var index = 1;
    var billAllData = new BillAllData();
    //银行
    billAllData.setBankName("光大银行");
    var cal = Calendar.getInstance();
    var theDay = cal.get(Calendar.DAY_OF_MONTH);
    //判断当前时间是否大于18号，如果大于，未出账单的月份为下月的18号，如果小于等于18号，则为当月的18号
    if(theDay > parseInt(the_bill_day)){
        cal.add(Calendar.MONTH, 1);
    }

    var moth = yyyy_MM_dd_FORMAT.format(cal.getTime());
    //账单日
    billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(moth.substring(0, 7) + "-" + the_bill_day))
    //账单编号
    billAllData.setBillId(UUID.randomUUID().toString());
    //账单月份
    billAllData.setBillMonth(moth.substring(0, 7));
    //账单类型
    billAllData.setBillType("UNDONE");
    //预借现金额度
    billAllData.setCashLimit(context.get("cash_limit"));
    //上期账单金额
    billAllData.setLastBalance(null);
    //上期还款金额
    billAllData.setLastPayment(null);
    //利息
    billAllData.setInterest(null);
    //预借现金额度美元
    billAllData.setUsdCashLimit(null);
    //信用卡额度美元
    billAllData.setUsdCreditLimit(null);
    //利息美元
    billAllData.setUsdInterest(null);
    //上期账单金额美元
    billAllData.setUsdLastBalance(null);
    //上期还款金额美元
    billAllData.setUsdLastPayment(null);
    //最低还款金额美元
    billAllData.setUsdMinPayment(null);
    //本期账单金额美元
    billAllData.setUsdNewBalance(null);
    //本期新增款额美元
    billAllData.setUsdNewCharges(null);
    // billAllData.setNewBalance(getBigDecimalByString(map.get("new_balance")));
    //判断map中的最低还款金额是否为空，来确定最低还款金额的值
    if (map.get("min_payment") != null) {
        billAllData.setMinPayment(getBigDecimalByString(map.get("min_payment")));
    } else {
        billAllData.setMinPayment(null);
    }
    //判断map中的信用卡额度是否为空，来确定信用卡额度的值
    if (map.get("credit_limit") != null) {
        billAllData.setCreditLimit(getBigDecimalByString(map.get("credit_limit")));
    } else {
        billAllData.setCreditLimit(null);
    }
    var cals = Calendar.getInstance();
    //判断map中的还款日是否为空，来确定还款日的值
    if (map.get("payment_due_date") == null || map.get("payment_due_date").equals("")) {
        billAllData.setPaymentDueDate(null);
    } else {
        cals.setTime(yyyy_MM_dd_FORMAT.parse(map.get("payment_due_date")));
        cals.add(Calendar.MONTH, 1);
        var due_date = yyyy_MM_dd_FORMAT.format(cals.getTime());
        billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(due_date));
    }
    var shopping_sheets = new ArrayList();
    var installments = new ArrayList();

    //解析未出账单页面
    paraseUnBillHtml(unbillHtml, shopping_sheets, index);
    var unbillMap = new HashMap();
    //获取未出账单的请求的参数
    var flag = paraseunbillParams(unbillHtml, unbillMap);
    //根据判断查询未出账单信息是否失败
    while (flag) {
        //获取未出账单页面
        unbillHtml = RequestUtil.post("https://xyk.cebbank.com/mycard/bill/unprintbill-query.htm", unbillMap);
        //保存页面
        storeDataToFile(context, unbillHtml, i + "_unbillHtml_" + num + ".html")
        //判断查询账单信息是否失败
        if (unbillHtml.contains("查询未出账单信息失败")) {
            flag = false;
            break;
        }
        //解析未出账单页面
        paraseUnBillHtml(unbillHtml, shopping_sheets, index);
        //获取未出账单的请求参数
        flag = paraseunbillParams(unbillHtml, unbillMap);
        num++;
    }
    var money = new BigDecimal("0.0");
    for each(var exp in shopping_sheets) {
        //获取消费金额
        var amount = exp.getAmountMoney();
        //如果消费金额为null，则本期新增款额为上文中的money+消费金额
        if(amount==null){
            money = money.add(new BigDecimal("0.0"));
            //如果消费金额不为null或者消费金额为正
        }else if (amount != null && amount.signum() == 1) {
            money = money.add(amount);
        }
    }
    //本期账单金额
    billAllData.setNewBalance(money);
    cal.setTime(cal.getTime());
    cal.add(Calendar.MONTH, -1);
    var currdate = cal.getTime();
    var currmoth = yyyy_MM_dd_FORMAT.format(currdate);
    currmoth = currmoth.substring(0, 7);
    for each(var billData in bills) {
        print("currmoth.... :"+currmoth)
        print("billmoth.... :"+billData.getBillMonth());
        if (currmoth.equals(billData.getBillMonth())) {
            var currBalance = money.add(billData.getNewBalance());
            //本期账单金额
            billAllData.setNewBalance(currBalance);
            //上期账单金额
            billAllData.setLastBalance(billData.getNewBalance());
        }
    }

    //计算上期还款金额,取上期的
    var payment_money = new BigDecimal("0.0");
    for each(var exp in shopping_sheets) {
        //获取消费金额
        var payment_amount = exp.getAmountMoney();
        //根据判断账单金额是否为负值来计算上期还款金额
        if (payment_amount!=null && payment_amount.signum() == -1) {
            payment_money = payment_money.add(payment_amount);
        }
    }
    //上期还款金额
    billAllData.setLastPayment(null);
    billAllData.setMinPayment(null);
    //本期新增款额
    billAllData.setNewCharges(money.compareTo(BigDecimal.ZERO)==0.00 ? null : money);
    billAllData.setShoppingSheets(shopping_sheets);
    bills.add(billAllData);
}

/**
 * 解析未出账单的页面
 * @param unbillHtml
 * @param shopping_sheets
 * @param index
 */
function paraseUnBillHtml( unbillHtml, shopping_sheets,  index) {
    //解析未出账单页面
    var doc = Jsoup.parse(unbillHtml);
    var trs = doc
        .select("body > table > tbody > tr:not(:first-child)");
    for (var i = 0; i < trs.size(); i++) {
        var exp = new Expense();
        var tr = trs.get(i);
        var tds = tr.select("td");
        //获取交易时间
        var trans_date = tds.get(0).text();
        //获取记账日期
        var post_date = tds.get(1).text();
        //获取卡号
        var card_num = tds.get(2).text().replace(/&nbsp;/ig,'');
        if(StringUtils.isBlank(card_num)){
            card_num = context.get("shopping_card_num");
        }
        //获取描述
        var description = tds.get(3).text().replace(/&nbsp;/ig,'');
        //获取其交易金额
        var amount_money = tds.get(4).text();
        //交易时间
        exp.setTransDate(yyyyMMdd_PARSER.parse(trans_date));
        //记账日
        exp.setPostDate(yyyy_MM_dd_PARSER.parse(post_date));
        //卡号
        exp.setCardNum(card_num);
        //币种
        exp.setCurrencyType("CNY");
        //编号
        exp.setId(UUID.randomUUID().toString());
        //描述
        exp.setDescription(description);
        //账户余额
        exp.setBalance(null);

        exp.setTransAddr("");//交易地点
        exp.setTransMethod("");//交易方式
        exp.setTransChannel("");//交易通道
        exp.setRemark("");//备注
        exp.setOppositeCardNo("");//对方卡号
        exp.setNameOnOppositeCard("");//对方持卡人
        exp.setOppositeBank("");//对方银行

        //判断交易金额是存入还是支出，如果是存入交易金额字段为负
        if (amount_money.contains("存入")) {
            exp.setAmountMoney(new BigDecimal(amount_money.replaceAll("存入", "")).negate());
        } else {
            exp.setAmountMoney(new BigDecimal(amount_money));
        }
        //编号
        exp.setOrderIndex(index++);
        //根据描述判断消费类型
        exp.setCategory(CategoryUtil.getCreditCategory("CEB", description, exp.getAmountMoney().toString()));
        shopping_sheets.add(exp);
    }
}

/**
 * 解析账单页面
 * @param billHtml
 * @param bills
 * @param bill_moth
 */
function paraseBillHtml( billHtml,  bills,  bill_moth) {
    //判断是否有账单记录
    if (billHtml.contains("无账单记录")) {
        logger.error("任务" +  context.get(LUA_TASK_KEY) + "账单信息-" + bill_moth + ":无账单记录");
        return;
    } else if (billHtml.contains("您目前没有登录，请登录后进行此操作")) {
        logger.error("任务" +  context.get(LUA_TASK_KEY) + "账单信息-" + bill_moth + ":无账单记录");
        return;
    }
    //解析账单信息
    var doc = Jsoup.parse(billHtml);
    var billAllData = new BillAllData();
    //银行
    billAllData.setBankName("光大银行");
    var bill_date = doc.select("body > div:nth-child(4) > div:nth-child(2) > table:nth-child(2) > tbody > tr:nth-child(2) > td:nth-child(1)").text();
    if(StringUtils.isNotBlank(bill_date)){
        //账单日
        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(bill_date.replaceAll("/", "-")));
        the_bill_day = bill_date.substring(8,10)
    }
    var buffer = new StringBuffer(bill_moth.substring(0, 6));
    buffer.insert(4, "-");
    //账单月份
    billAllData.setBillMonth(buffer.toString());
    //账单编号
    billAllData.setBillId(UUID.randomUUID().toString());
    //还款日
    var payment_due_date = doc
        .select("body > div:nth-child(4) > div:nth-child(2) > table:nth-child(2) > tbody > tr:nth-child(2) > td:nth-child(2)")
        .text();
    if(StringUtils.isNotBlank(payment_due_date)){
        billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(payment_due_date.replaceAll("/", "-")));
    }
    var scripts = doc
        .select("body > div:nth-child(4) > div:nth-child(2) > table:nth-child(2) > tbody > tr:nth-child(2) > td:nth-child(3) > script");
    //信用卡额度
    var credit_limit = getDataNodeToString(scripts);
    //账单类型
    billAllData.setBillType("DONE");
    var scriptn = doc
        .select("body > div:nth-child(4) > div:nth-child(2) > table:nth-child(2) > tbody > tr:nth-child(4) > td:nth-child(1) > script");
    //本期账单金额
    var new_balance = getDataNodeToString(scriptn);
    billAllData.setNewBalance(getStringToBigDecimal(new_balance));
    var scriptm = doc
        .select("body > div:nth-child(4) > div:nth-child(2) > table:nth-child(2) > tbody > tr:nth-child(4) > td:nth-child(2) > script");
    //最低还款额度
    var min_payment = getDataNodeToString(scriptm);
    billAllData.setMinPayment(getStringToBigDecimal(min_payment));
    //账单类型
    billAllData.setBillType("DONE");
    //预借现金额度
    billAllData.setCashLimit(context.get("cash_limit"));
    //信用额度
    billAllData.setCreditLimit(getStringToBigDecimal(credit_limit));
    //上期账单金额
    billAllData.setLastBalance(null);
    //上期还款额度
    billAllData.setLastPayment(null);
    //利息
    billAllData.setInterest(null);
    //预借现金额度美元
    billAllData.setUsdCashLimit(null);
    //信用额度美元
    billAllData.setUsdCreditLimit(null);
    //利息美元
    billAllData.setUsdInterest(null);
    //上期账单金额美元
    billAllData.setUsdLastBalance(null);
    //上期还款额度美元
    billAllData.setUsdLastPayment(null);
    //最低还款额度美元
    billAllData.setUsdMinPayment(null);
    //本期账单金额美元
    billAllData.setUsdNewBalance(null);
    //本期新增款额美元
    billAllData.setUsdNewCharges(null);
    var index = 1;
    var shopping_sheets = new ArrayList();
    var installments = new ArrayList();
    var trs = doc.select("body > div:nth-child(4) > div:nth-child(4) > div:nth-child(2) > table:nth-child(2) > tbody > tr.items > td > table:nth-child(2) > tbody > tr:not(:first-child):not(:nth-child(2))");
    for (var i = 0; i < trs.size() - 1; i++) {
        // logger.info("打印："+i);
        var exp = new Expense();
        var tr = trs.get(i);
        var tds = tr.select("td");
        var trans_date = tds.get(0).text();
        var post_date = tds.get(1).text();
        var card_num = tds.get(2).text().replace(/&nbsp;/ig,'').replace(/\?/ig,"").trim();
        if(StringUtils.isBlank(card_num)){
            card_num = context.get("shopping_card_num");
        }
        var description = tds.get(3).text().replace(/&nbsp;/ig,'').replace(/\?/ig,"").trim();

        var scripta = tds.get(4).select("script").get(0)
            .dataNodes();
        var amount_money = scripta.get(0).toString();
        //exp 中为null的字段要转换成“”
        exp.setTransAddr("");//交易地点
        exp.setTransMethod("");//交易方式
        exp.setTransChannel("");//交易通道
        exp.setRemark("");//备注
        exp.setOppositeCardNo("");//对方卡号
        exp.setNameOnOppositeCard("");//对方持卡人
        exp.setOppositeBank("");//对方银行


        //账户余额
        exp.setBalance(null);
        //交易时间
        exp.setTransDate(yyyyMMdd_PARSER
            .parse(trans_date));
        //记账日期
        exp.setPostDate(yyyyMMdd_PARSER
            .parse(post_date));
        //卡号
        exp.setCardNum(card_num.replaceAll(" || ", ""));
        //描述
        exp.setDescription(description);
        //编号
        exp.setId(UUID.randomUUID().toString());
        //通过匹配正则获取所需字段
        var money = RegexUtils.GetText(description, " 账单分期 \\(分期\\) ([^a-zA-Z]+)");
        var install = RegexUtils.GetText(description, "月份账单账单分期([^']*?)期：");
        var inttall = RegexUtils.GetText(description, "月份账单取现分期([^']*?)期：");

        var inmtall = RegexUtils.GetText(description, " 账单分期分月 \\(分期\\) ([^a-zA-Z]+)");
        var inatall = RegexUtils.GetText(description, "月份账单交易分期\\(手续费分月等额支付\\)([^']*?)期：");
        var inztall = RegexUtils.GetText(description, " 账单分期 ([0-9]{1,10},[0-9]{3}.[0-9]{1,2}?$)");
        var inktall = RegexUtils.GetText(description, " 账单分期 (\\d+\\.00)");
        var inytall = RegexUtils.GetText(description, "月份账单邮购分期([^']*?)期：");
        var inntall = RegexUtils.GetText(description, "月份账单自选分期([^']*?)期：");
        var inwtall = RegexUtils.GetText(description, " 账单分期 (\\d+\\.\\d)");

        //账单金额
        var amountMoney;

        //分期月数
        var install_month =null;
        var current_month = null;//当前期数
        if (StringUtils.isNotEmpty(install) || StringUtils.isNotEmpty(inttall)) {
            var mon = RegexUtils.GetText(description, "本期应还款([^，]*?)，");
            //exp.setAmountMoney();
            install_month = StringUtils.isNotEmpty(install)? parseInt(install) : parseInt(inttall);
            current_month = install_month - (StringUtils.isNotEmpty(RegexUtils.GetText(description,"余期为(\\d+)期")) ? parseInt(RegexUtils.GetText(description,"余期为(\\d+)期")) : 0);
            amountMoney = new BigDecimal(mon.replaceAll(",", ""))
        } else if (StringUtils.isNotEmpty(money)) {
            //exp.setAmountMoney();
            //install_month = StringUtils.isNotEmpty(install)? parseInt(install) : null;
            amountMoney = new BigDecimal(money.replaceAll(",", ""))
        } else if (StringUtils.isNotEmpty(inmtall)) {
            //exp.setAmountMoney();
            amountMoney = new BigDecimal(inmtall.replaceAll(",", ""));
        } else if (StringUtils.isNotEmpty(inatall)) {
            var mon = RegexUtils.GetText(description, "本期应还款([^，]*?)，");
            install_month = parseInt(inatall)
            current_month = install_month - (StringUtils.isNotEmpty(RegexUtils.GetText(description,"余期为(\\d+)期")) ? parseInt(RegexUtils.GetText(description,"余期为(\\d+)期")) : 0);
            //exp.setAmountMoney();
            amountMoney = new BigDecimal(mon.replaceAll(",", ""));
        } else if (StringUtils.isNotEmpty(inztall)) {
            //exp.setAmountMoney(new BigDecimal(inztall.replaceAll(",", "")));
            amountMoney = new BigDecimal(inztall.replaceAll(",", ""));
        } else if (StringUtils.isNotEmpty(inktall)) {
            var mon = RegexUtils.GetText(description," 账单分期 (\\d+\\.00)");
            //exp.setAmountMoney(new BigDecimal(mon.replaceAll(",", "")));
            amountMoney = new BigDecimal(mon.replaceAll(",", ""))
        } else if (StringUtils.isNotEmpty(inytall)) {
            var mon = RegexUtils.GetText(description, "本期应还款([^，]*?)，");
            install_month = parseInt(inytall);
            current_month =install_month - (StringUtils.isNotEmpty(RegexUtils.GetText(description,"余期为(\\d+)期")) ? parseInt(RegexUtils.GetText(description,"余期为(\\d+)期")) : 0);
            //exp.setAmountMoney(new BigDecimal(mon.replaceAll(",", "")));
            amountMoney = new BigDecimal(mon.replaceAll(",", ""))
        } else if (StringUtils.isNotEmpty(inntall)) {
            var mon = RegexUtils.GetText(description, "本期应还款([^，]*?)，");
            install_month = parseInt(inntall);
            current_month =install_month - (StringUtils.isNotEmpty(RegexUtils.GetText(description,"余期为(\\d+)期")) ? parseInt(RegexUtils.GetText(description,"余期为(\\d+)期")) : 0);
            //exp.setAmountMoney(new BigDecimal(mon.replaceAll(",", "")));
            amountMoney = new BigDecimal(mon.replaceAll(",", ""))
        } else if (StringUtils.isNotEmpty(inwtall)) {
            var mon = RegexUtils.GetText(description, " 账单分期 (\\d+\\.\\d)");
            //exp.setAmountMoney(new BigDecimal(mon.replaceAll(",", "")));
            amountMoney = new BigDecimal(mon.replaceAll(",", ""));
        } else {
            amount_money = RegexUtils.GetText(amount_money, "document.write\\(billQueryDetail1\\('([^']*?)'\\)\\)");
            if(amount_money.isEmpty()){
                //exp.setAmountMoney(null);
                amountMoney = null;
            }else{
                //exp.setAmountMoney(new BigDecimal(amount_money));
                amountMoney = new BigDecimal(amount_money);
            }
        }

        exp.setAmountMoney(amountMoney);
        //分期金额
        var handingFee = null;
        var tempdesc = description.replaceAll(",","");
        var tempHandFee = RegexUtils.GetText(tempdesc,"手续费(\\d+\\.\\d)");
        if(description.contains("分期") && description.contains("手续费") && StringUtils.isNotBlank(tempHandFee)){
            var mon = RegexUtils.GetText(tempdesc, "手续费(\\d+\\.\\d)");
            handingFee = new BigDecimal(mon.replaceAll(",", ""));
        }

        //将分期数据添加进分期列表，手续费除外
        if(description.contains("分期") && install_month!=null && current_month!=null && !description.contains("账单分期 (分期)")){
            var ins = new Installment();
            ins.setInstallmentDesc(description);//分期描述
            ins.setHandingfeeDesc("");//分期手续费描述
            ins.setBillId(UUID.randomUUID().toString());//分期编号
            ins.setTransDate(yyyyMMdd_PARSER.parse(trans_date));//交易时间
            ins.setPostDate(yyyyMMdd_PARSER.parse(post_date));//记账日期
            ins.setShoppingsheetId(UUID.randomUUID().toString());//消费记录
            ins.setInstallmentType("BILL");//分期类型
            ins.setTransferFee(null);//转账手续费
            ins.setTotalMonth(install_month);//总分期数
            ins.setCurrentMonth(current_month);//当前分期数
            ins.setAmountMoney(amountMoney);//本期金额
            ins.setCurrencyType("CNY");//币种
            ins.setHandingFee(handingFee);//本期手续费
            ins.setTransferfeeDesc("");
            installments.add(ins);
        }
        //币种
        exp.setCurrencyType("CNY");
        //根据描述判断消费类型
        exp.setCategory(CategoryUtil.getCreditCategory("CEB", description,
            exp.getAmountMoney()==null?null:exp.getAmountMoney().toString()));
        //编号
        exp.setOrderIndex(index++);
        shopping_sheets.add(exp);
    }
    var money = new BigDecimal("0.0");
    for each(var exp in shopping_sheets) {
        //获取交易金额
        var amount = exp.getAmountMoney();
        //判断交易金额是否为正
        if (amount != null && amount.signum() == 1) {
            money = money.add(amount);
        }
    }
    //本期新增款额
    billAllData.setNewCharges(money);
    var payment_money = new BigDecimal("0.0");
    for each(var exp in shopping_sheets) {
        //获取交易金额
        var payment_amount = exp.getAmountMoney();
        //判断交易金额是否为负，如果为负数相加即为本期新增款额
        if (payment_amount!=null && payment_amount.signum() == -1) {
            payment_money = payment_money.add(payment_amount);
        }
    }
    //上期还款金额
    billAllData.setLastPayment(payment_money);
    var cal = Calendar.getInstance();
    cal.setTime(billAllData.getBillDate());
    cal.add(Calendar.MONTH, -1);
    var currdate = cal.getTime();
    var currmoth = yyyy_MM_dd_FORMAT.format(currdate);
    currmoth = currmoth.substring(0, 7);
    for each(var billData in bills) {
        if (currmoth.equals(billData.getBillMonth())) {
            //上期账单金额
            billAllData.setLastBalance(billData.getNewBalance());
        }
    }
    billAllData.setShoppingSheets(shopping_sheets);
    billAllData.setInstallments(installments);
    bills.add(billAllData);
}

/**
 * 获取list下的某个元素
 * @param scripts
 * @returns {string}
 */
function getDataNodeToString( scripts) {
    var scriptList = scripts.get(0).dataNodes();
    var datanode = scriptList.get(0);
    return datanode.toString();
}

/**
 * 将string类型的值转换为bigdecimal类型
 * @param credit_limit
 * @returns {BigDecimal}
 */
function getStringToBigDecimal( credit_limit) {
    var result = RegexUtils.GetText(credit_limit,
        "document.write\\(formatCurrency\\('([^']*?)'\\)\\)");
    return new BigDecimal(result);
}

/**
 * 将string类型转换为bigdecimal
 * @param val
 * @returns {BigDecimal}
 */
function getBigDecimalByString( val) {
    //将多余的字段都替换为空并滤空
    val = val.replaceAll(",", "")
        .replaceAll("/RMB", "")
        .replaceAll("人民币：| ", "")
        .replaceAll("美元", "")
        .replaceAll(" ", "")
        .trim();
    var bigDecimal = new BigDecimal(val);
    return bigDecimal;
}

/**
 * 获取基本参数
 * @param baseHtml
 * @param postdata
 * @param cardNum
 */
function paraseBaseParams( baseHtml, postdata,  cardNum) {
    var userDoc = Jsoup.parse(baseHtml);
    var ss = userDoc.getElementsByTag("form");
    var billinfoform = userDoc.getElementById("type");
    var scriptList = billinfoform.getAllElements();
    var inputs = userDoc
        .select("input:not([name='type']):not([name='cardno'])");
    for each(var input in inputs) {
        postdata.put(input.attr("name"), input.attr("value"));
    }
    postdata.put("type", "lb");
    postdata.put("cardno", cardNum);

}

/**
 * 获取未出账单的请求的参数
 * @param unbillHtml
 * @param unbillMap
 * @returns {boolean}
 */
function paraseunbillParams( unbillHtml, unbillMap) {
    //判断是否登录
    if (unbillHtml.contains("您目前没有登录，请登录后进行此操作 ")) {
        return false;
    }
    if(unbillHtml.contains("No backend server available for connection")){
        return false;
    }
    //解析未出账单页面
    var unbillDoc = Jsoup.parse(unbillHtml);
    var queryForm = unbillDoc.getElementById("form4");
    //获取请求的参数
    var START_SEQ_NBR = paraseParams(queryForm, "START_SEQ_NBR");
    var START_STMT_DATE = paraseParams(queryForm, "START_STMT_DATE");
    var START_TYPE = paraseParams(queryForm, "START_TYPE");
    var MORE_IND = paraseParams(queryForm, "MORE_IND");
    var ACCT_NBR = paraseParams(queryForm, "ACCT_NBR");
    var ORG = paraseParams(queryForm, "ORG");
    var totalpage = RegexUtils.GetText(unbillHtml,
        "processPagingEvents2\\('form4', '([^']*?)'");
    var currentPage = RegexUtils.GetText(unbillHtml,
        "currentPage = '([^']*?)'");
    var isnext = RegexUtils.GetText(unbillHtml, "var isnext = '(Y|N)';");

    unbillMap.put("START_SEQ_NBR", START_SEQ_NBR);
    unbillMap.put("START_STMT_DATE", START_STMT_DATE);
    unbillMap.put("START_TYPE", START_TYPE);
    unbillMap.put("MORE_IND", MORE_IND);
    unbillMap.put("ACCT_NBR", ACCT_NBR);
    unbillMap.put("ORG", ORG);
    unbillMap.put("currentpage", currentPage + "1");
    unbillMap.put("totalpage", totalpage);

    if (isnext.equals("Y")) {
        return true;
    } else {
        return false;
    }
}

/**
 * 获取某元素内的有个字段的value值
 * @param form
 * @param element
 * @returns {*}
 */
function paraseParams(form,  element) {
    var elements = form.select("[name='" + element + "']");
    return elements.get(0).attr("value");
}

/**
 * 判断字符串是否是json格式
 * @param str
 * @returns {boolean}
 */
function strIsJSON(str) {
    if (typeof str == 'string') {
        try {
            var obj=JSON.parseObject(str);
            if(typeof obj == 'object' && obj ){
                return true;
            }else{
                return false;
            }

        } catch(e) {
            print('error：'+str+'!!!'+e);
            return false;
        }
    }
    print.log('It is not a string!')
}